﻿using FreeSql.Internal.Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using MiniExcelLibs;
using Mohe.Scada.Util.Helper;
using Mohe.Scada.Util.Models;
using Mohe.Scada.WebApi.Cache;
using Mohe.Scada.WebApi.Common;
using Mohe.Scada.WebApi.Helper;
using Mohe.Scada.WebApi.Models;
using Mohe.Scada.WebApi.Services;
using Newtonsoft.Json;
using NLog;
using System.Globalization;
using System.Reflection;
using System.Text;

namespace Mohe.Scada.WebApi.Controllers
{
    [Route("api/[controller]"), ApiController]
    public class AppCurdController<T> : Controller where T : class, new()
    {
        private static Logger _logger = LogManager.GetCurrentClassLogger();
        protected JwtPayload CurrentUser;
        protected readonly ICurdService<T> service;
        protected readonly bool isIntKey;
        protected readonly IFreeSql freeSql;
        protected Dictionary<string, object> _originalEntities = new();
        public AppCurdController(IFreeSql appDb, bool isIntKey = true)
        {
            this.service = new BaseCurdService<T>(appDb);
            this.isIntKey = isIntKey;
            this.freeSql = appDb;

        }


        //private List<DynamicFilterInfo> GetFilters(string where)
        //{
        //    var filters = new List<DynamicFilterInfo>();
        //    if (!where.IsNullOrEmpty())
        //    {
        //        filters = JsonHelper.FromJson<List<DynamicFilterInfo>>(System.Web.HttpUtility.UrlDecode(where));
        //    }
        //    return filters;
        //}

        /// <summary>新增前的验证</summary>
        /// <returns></returns>
        protected virtual ApiResult VerifyAdd(T model)
        {
            return ApiResult.Success();
        }

        /// <summary>判断是否为无效主键</summary>
        /// <param name="id">主键（字符串）</param>
        /// <param name="intId">主键（整形）</param>
        /// <returns>Boolean</returns>
        [NonAction]
        protected int IsInvalidId(String id)
        {
            int intId = 0;
            Boolean result;
            if (isIntKey)
            {
                result = !Int32.TryParse(id, out intId) || intId < 0;
            }
            return intId;
        }

        /// <summary>编辑前的验证</summary>
        /// <returns></returns>
        protected virtual ApiResult VerifyEdit(T model)
        {
            return ApiResult.Success();
        }

        /// <summary>新增</summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost("Save")]
        public virtual ApiResult Add([FromBody] ParameterModel model)
        {
            if (model.Count == 0)
                return ApiResult.Fail("没有获取到对象参数 model ");

            var entity = model.Read<T>();
            var verify = VerifyAdd(entity);
            if (!verify.IsSuccess)
                return verify;
            return ApiResult.Operation(service.Add(entity));
        }

        /// <summary>编辑</summary>
        /// <param name="id"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost("Update")]
        public virtual ApiResult Edit([FromBody] ParameterModel model)
        {
            //model.Remove("Id");
            model.Remove("CreateTime");

            if (model.Count == 0)
                return ApiResult.Fail("没有获取到对象参数 model ");

            if (model.TryGetValue("Id", out object idVal))
            {
                string id = idVal.ToString();
                var intId = IsInvalidId(id);

                var entity = service.Get(isIntKey ? intId : id);
                var addEntity = model.Read<T>();
                if (entity is null)
                {
                    var addVerify = VerifyAdd(entity);
                    if (!addVerify.IsSuccess)
                        return addVerify;
                    return ApiResult.Operation(service.Add(addEntity));

                }

                var verify = VerifyEdit(entity);
                if (!verify.IsSuccess)
                    return verify;
                return ApiResult.Operation(service.Edit(isIntKey ? intId : id, model));

            }
            else
            {
                return ApiResult.Fail("Id不存在 ");
            }
        }

        /// <summary>物理删除</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("DeleteData/{ids}")]
        public virtual ApiResult Delete(string ids)
        {
            freeSql.Transaction(() =>
            {
                var idArr = ids.Split(',');
                foreach (var id in idArr)
                {
                    var intId = IsInvalidId(id);
                    service.Delete(isIntKey ? intId : id);
                }
            });
            return ApiResult.Success();
        }



        /// <summary>获取模型</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("GetById/{id}")]
        public virtual ApiResult GetById(string id)
        {
            var intId = IsInvalidId(id);

            var entity = service.Get(isIntKey ? intId : id);
            if (entity is null)
                return ApiResult.Fail("数据不存在");
            return ApiResult.Success(entity);
        }

        /// <summary>获取模型</summary>
        /// <param name="filterRequest"></param>
        /// <returns></returns>
        [HttpPost("Get")]
        public virtual ApiResult Get([FromBody] ListRequest req)
        {
            var filters = new DynamicFilterInfo();
            if (!string.IsNullOrEmpty(req.Where))
            {
                filters = JsonConvert.DeserializeObject<DynamicFilterInfo>(req.Where);
            }
            return ApiResult.Success(service.Get(filters));
        }

        /// <summary>获取列表</summary>
        /// <param name="where">查询条件 And Or 查询 不支持嵌套</param>
        /// <returns></returns>
        [HttpPost("List")]
        public virtual ApiResult List([FromBody] ListRequest req)
        {
            var filters = new DynamicFilterInfo();
            if (!string.IsNullOrEmpty(req.Where))
            {
                filters = JsonConvert.DeserializeObject<DynamicFilterInfo>(req.Where);
            }
            return ApiResult.Success(service.List(filters));
        }

        /// <summary>获取分页列表</summary>
        /// <param name="pageRequest"></param>
        /// <returns></returns>
        [HttpPost("GetPageList")]
        public virtual ApiPageResult Page([FromBody] PageRequest pageRequest)
        {
            return service.Page(pageRequest);
        }
        [HttpPost("Import")]
        public virtual ApiResult Import()
        {

            var file = Request.Form.Files[0];
            using (var stream = file.OpenReadStream())
            {
                try
                {
                    var rows = stream.Query<T>().ToList();
                    freeSql.Transaction(() =>
                    {
                        freeSql.Insert(rows).ExecuteAffrows();
                    });
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                    return ApiResult.Fail(ex.Message);
                }

            }
            return ApiResult.Success();
        }

        [HttpPost("Export")]
        public virtual IActionResult Export([FromBody] ListRequest req)
        {
            var filters = new DynamicFilterInfo();
            if (!string.IsNullOrEmpty(req.Where))
            {
                filters = JsonConvert.DeserializeObject<DynamicFilterInfo>(req.Where);
            }
            var res = service.List(filters);
            using (var ms = new MemoryStream())
            {
                //var values = new List<Dictionary<string, object>>();
                //var properties = typeof(T).GetProperties();
                //foreach (var item in res)
                //{
                //    var dataItem = new Dictionary<string, object>();
                //    foreach (var property in properties)
                //    {
                //        dataItem.Add(GetLocalizer(property.Name), property.GetValue(item));
                //    }
                //    values.Add(dataItem);
                //}

                MiniExcel.SaveAs(ms, res);
                return File(ms.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Export.xlsx");
            }
        }

        private IActionResult ToJsonContent(object obj)
        {
            return Content(obj.ToJson());
        }





    }
}
